package com.unlcn.ils.kas.service.order.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.collect.Maps;
import com.unlcn.ils.kas.dao.model.order.OrderOtd;
import com.unlcn.ils.kas.dao.model.order.OrderOtdDetail;
import com.unlcn.ils.kas.dao.model.order.OrderOtdLogDetail;
import com.unlcn.ils.kas.service.map.BaiDuMap.util.BaiDuMapGeocodeUtil;
import com.unlcn.ils.kas.service.map.BaiDuMap.util.BaiDuMapRouteUtil;
import com.unlcn.ils.kas.service.order.GetOrderOnWayService;
import com.unlcn.ils.kas.service.order.OrderOtdDetailService;
import com.unlcn.ils.kas.service.order.OrderOtdService;
import com.unlcn.ils.kas.service.util.BaseException;
import com.unlcn.ils.kas.service.util.ErpUrl;
import com.unlcn.ils.kas.service.util.HttpClientUtil;
import com.unlcn.ils.kas.service.util.enums.order.OrderDetailDeleteFlagEnum;
import com.unlcn.ils.kas.service.util.enums.order.OrderDetailIsmanualEnum;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lenovo on 2018/4/24.
 */
@Service
public class GetOrderOnWayServiceImpl implements GetOrderOnWayService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SharesOrderServiceImpl.class);

    @Autowired
    private OrderOtdService orderOtdService;

    @Autowired
    private OrderOtdDetailService orderOtdDetailService;

    /**
     * erp 接口地址 model
     */
    @Autowired
    private ErpUrl erpUrl;

    @Override
    public List<Map<String, String>> getOnWay(String[] sysOrderNos) {

        LOGGER.info("GetOrderOnWayServiceImpl.getOnWay（手动根据订单号获取在途信息） params: " + sysOrderNos);

        if (sysOrderNos==null || sysOrderNos.length==0)
            throw new BaseException("订单号不能为空！");

        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        List<Map<String, String>> result = new ArrayList<>();
        for (String sysOrderNo : sysOrderNos) {

            sysOrderNo = sysOrderNo.trim();

            Map<String, String> map = new HashMap<>();

            try {
                Wrapper<OrderOtd> ew = new EntityWrapper<>();
                ew.eq("sys_order_no", sysOrderNo);
                List<OrderOtd> orderOtdList = orderOtdService.selectList(ew);
                if (CollectionUtils.isEmpty(orderOtdList)) {
                    map.put("sysOrderNo", sysOrderNo);
                    map.put("msg", "不存在此订单号");
                    result.add(map);
                    LOGGER.info("GetOrderOnWayServiceImpl.getOnWay ： 不存在拉取的订单号（" + sysOrderNo + "） ");
                    continue;
                }
                OrderOtd orderOtd = orderOtdList.get(0);

                List<NameValuePair> onWayParams = new ArrayList<>();
                onWayParams.add(new BasicNameValuePair("vcdn", sysOrderNo));
                String onWayResult = HttpClientUtil.get(erpUrl.getGetErpOnway(), onWayParams, 600000000);

                Integer getNum = 0;
                if (!StringUtils.isEmpty(onWayResult)) {
                    // 将在途信息转换成map集合
                    List<Map> onWayList = getMap(onWayResult);

                    LOGGER.info("GetOrderOnWayServiceImpl.getOnWay : "+ sysOrderNo + "订单存在" + onWayList.size() + "条在途");

                    if (!CollectionUtils.isEmpty(onWayList)) {
                        for (Map onWayMap : onWayList) {
                            OrderOtdDetail orderOtdDetail = analysisOnWayInfo(onWayMap);

                            // 不保存重复在途信息
                            Wrapper<OrderOtdDetail> detailEntity = new EntityWrapper();
                            detailEntity.eq("track_time", simpleDateFormat.format(orderOtdDetail.getTrackTime()));
                            detailEntity.eq("sys_order_no", orderOtdDetail.getSysOrderNo());
                            List<OrderOtdDetail> orderOtdDetails = orderOtdDetailService.selectList(detailEntity);
                            if (!CollectionUtils.isEmpty(orderOtdDetails))
                                continue;

                            // 计算运输距离
                            Number distance = computationalDistance(orderOtd, orderOtdDetail);
                            orderOtdDetail.setDistance(distance.floatValue());

                            // 查看存不存在比手动维护的时间要晚，并且距离要远的数据
                            Wrapper<OrderOtdDetail> wrapper = new EntityWrapper<>();
                            wrapper.eq("sys_order_no", orderOtdDetail.getSysOrderNo());
                            wrapper.eq("ismanual", OrderDetailIsmanualEnum.YES.getCode());
                            wrapper.lt("track_time", simpleDateFormat.format(orderOtdDetail.getTrackTime()));
                            wrapper.lt("distance", orderOtdDetail.getDistance());
                            wrapper.eq("isdelete", OrderDetailDeleteFlagEnum.NORMAL.getCode());
                            if (!CollectionUtils.isEmpty(orderOtdDetailService.selectList(wrapper)))
                                continue;

                            orderOtdDetail.setHeadId(orderOtd.getId());
                            orderOtdDetailService.insert(orderOtdDetail);
                            getNum ++;
                        }
                    }
                }

                // 更新主表更新时间
                OrderOtd updateOrder = new OrderOtd();
                updateOrder.setGmtModified(new Date());
                Wrapper<OrderOtd> orderOtdWrapper = new EntityWrapper<>();
                orderOtdWrapper.eq("sys_order_no", sysOrderNo);
                orderOtdService.update(updateOrder, orderOtdWrapper);

                map.put("sysOrderNo", sysOrderNo);
                map.put("msg", "成功拉取" + getNum + "条明细");
            } catch (Exception e) {
                LOGGER.error("GetOrderOnWayServiceImpl.getOnWay ERROR MESS: ", e);
                map.put("sysOrderNo", sysOrderNo);
                map.put("msg", "拉取失败");
                map.put("error", JSON.toJSONString(e));
            }

            result.add(map);
        }

        return result;
    }

    /**
     * 计算运输距离
     * @param orderOtd
     * @param orderOtdDetail
     * @return
     */
    public Number computationalDistance(OrderOtd orderOtd, OrderOtdDetail orderOtdDetail) {

        Number distance = 0.00;

        if (orderOtdDetail == null)
            return  distance;

        if (orderOtdDetail.getLatitude()==null || orderOtdDetail.getLongitude()==null) {
            // 计算运输距离
            String startAddress = orderOtdDetail.getProvince() + orderOtdDetail.getCity() + orderOtdDetail.getArea() + orderOtdDetail.getAddress();
            String endAddress = orderOtd.getdProvince() + orderOtd.getdCity() + orderOtd.getdAddress();
            distance = getDistance(startAddress, endAddress);
        } else {
            Map<String,Double> mapOrgrin = Maps.newHashMap();
            mapOrgrin.put("lat", Double.valueOf(orderOtdDetail.getLatitude().toString()));
            mapOrgrin.put("lng", Double.valueOf(orderOtdDetail.getLongitude().toString()));

            String cords = mapOrgrin.get("lng") + "," + mapOrgrin.get("lat");
            List<Map<String,Double>> lists = BaiDuMapGeocodeUtil.geoConv(cords,1,5);
            if (!CollectionUtils.isEmpty(lists)) {
                Map<String, Double> mapGeo = lists.get(0);

                String destination = null;

                // 根据详细地址获取距离
                destination = orderOtd.getdAddress();
                Map<String,Double> mapDestinations = BaiDuMapGeocodeUtil.addressToGPS(destination);
                distance = BaiDuMapRouteUtil.getDistance(mapGeo,mapDestinations)/1000;

                // 如果详细地址无法获取距离，则根据省市区加详细地址
                if (distance==null || 0>=distance.doubleValue()) {
                    destination = (orderOtd.getdProvince())==null?"":orderOtd.getdProvince()
                            + (orderOtd.getdCity())==null?"":orderOtd.getdCity()
                            + (orderOtd.getdAddress())==null?"":orderOtd.getdAddress();
                    mapDestinations = BaiDuMapGeocodeUtil.addressToGPS(destination);
                    distance = BaiDuMapRouteUtil.getDistance(mapGeo,mapDestinations)/1000;
                }
            }
        }

        return distance;
    }

    /**
     * 获取两地距离
     * @param startAddress
     * @param endAddress
     * @return
     */
    private Double getDistance(String startAddress, String endAddress) {

        if (StringUtils.isEmpty(startAddress)
                || StringUtils.isEmpty(endAddress))
            return 0.0;

        startAddress = startAddress.replaceAll("null", "");
        endAddress = endAddress.replaceAll("null", "");

        Double distance = BaiDuMapRouteUtil.getDistance(startAddress, endAddress);
        if (distance == null) {
            return 0.0;
        }
        distance = distance / 1000;

        return distance;
    }

    @Override
    public Integer getOnWayBySql(String sql) {

        Wrapper<OrderOtd> wrapper = new EntityWrapper<>();
        wrapper.addFilter(sql);

        List<OrderOtd> list = orderOtdService.selectList(wrapper);
        if (CollectionUtils.isEmpty(list))
            return 0;

        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int count = 0;
        for (OrderOtd orderOtd : list) {
            String sysOrderNo = orderOtd.getSysOrderNo().trim();

            try {
                List<NameValuePair> onWayParams = new ArrayList<>();
                onWayParams.add(new BasicNameValuePair("vcdn", sysOrderNo));
                String onWayResult = HttpClientUtil.get(erpUrl.getGetErpOnway(), onWayParams, 600000000);

                if (!StringUtils.isEmpty(onWayResult)) {
                    // 将在途信息转换成map集合
                    List<Map> onWayList = getMap(onWayResult);

                    LOGGER.info("GetOrderOnWayServiceImpl.getOnWay : "+ sysOrderNo + "订单存在" + onWayList.size() + "条在途");

                    if (!CollectionUtils.isEmpty(onWayList)) {
                        for (Map onWayMap : onWayList) {
                            OrderOtdDetail orderOtdDetail = analysisOnWayInfo(onWayMap);

                            // 不保存重复在途信息
                            Wrapper<OrderOtdDetail> detailEntity = new EntityWrapper();
                            detailEntity.eq("track_time", simpleDateFormat.format(orderOtdDetail.getTrackTime()));
                            detailEntity.eq("sys_order_no", orderOtdDetail.getSysOrderNo());
                            List<OrderOtdDetail> orderOtdDetails = orderOtdDetailService.selectList(detailEntity);
                            if (!CollectionUtils.isEmpty(orderOtdDetails))
                                continue;

                            orderOtdDetail.setHeadId(orderOtd.getId());
                            orderOtdDetailService.insert(orderOtdDetail);
                        }
                    }
                }

                // 更新主表更新时间
                OrderOtd updateOrder = new OrderOtd();
                updateOrder.setGmtModified(new Date());
                Wrapper<OrderOtd> orderOtdWrapper = new EntityWrapper<>();
                orderOtdWrapper.eq("sys_order_no", sysOrderNo);
                orderOtdService.update(updateOrder, orderOtdWrapper);

                count ++;
            } catch (Exception e) {
                LOGGER.error("GetOrderOnWayServiceImpl.getOnWay ERROR MESS: ", e);
            }
        }

        return count;
    }

    @Override
    public Integer updateOnWayId(String startTime, String endTime) {

        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Wrapper<OrderOtdDetail> ew = new EntityWrapper<>();
        ew.ge(" gmt_create ", startTime);
        ew.lt(" gmt_create ", endTime);
        List<OrderOtdDetail> orderOtdDetailList = orderOtdDetailService.selectList(ew);

        Integer num = 0;
        String sysOrderNo = "";
        String onWayResult = "";
        for (OrderOtdDetail orderOtdDetail : orderOtdDetailList) {
            try {
                if (StringUtils.isEmpty(sysOrderNo)) {
                    List<NameValuePair> onWayParams = new ArrayList<>();
                    onWayParams.add(new BasicNameValuePair("vcdn", orderOtdDetail.getSysOrderNo()));
                    onWayResult = HttpClientUtil.get(erpUrl.getGetErpOnway(), onWayParams, 600000000);
                } else {
                    if (!sysOrderNo.equals(orderOtdDetail.getSysOrderNo())
                            || StringUtils.isEmpty(onWayResult)) {
                        List<NameValuePair> onWayParams = new ArrayList<>();
                        onWayParams.add(new BasicNameValuePair("vcdn", orderOtdDetail.getSysOrderNo()));
                        onWayResult = HttpClientUtil.get(erpUrl.getGetErpOnway(), onWayParams, 600000000);
                    }
                }

                if (!StringUtils.isEmpty(onWayResult)) {
                    // 将在途信息转换成map集合
                    List<Map> onWayList = getMap(onWayResult);

                    for (Map map : onWayList) {
                        OrderOtdDetail detail = analysisOnWayInfo(map);
                        if (orderOtdDetail.getSysOrderNo().equals(detail.getSysOrderNo())
                                && simpleDateFormat.format(orderOtdDetail.getTrackTime()).equals(simpleDateFormat.format(detail.getTrackTime()))) {
                            OrderOtdDetail updateDetail = new OrderOtdDetail();
                            updateDetail.setId(orderOtdDetail.getId());
                            updateDetail.settId(detail.gettId());
                            orderOtdDetailService.updateById(updateDetail);

                            num ++;

                            break;
                        }
                    }
                }

                sysOrderNo = orderOtdDetail.getSysOrderNo();
            } catch (Exception e) {
                LOGGER.error("GetOrderOnWayServiceImpl.updateOnWayId", e);
                continue;
            }
        }

        return num;
    }

    /**
     * 格式化在途信息
     * @param map
     * @return
     */
    private OrderOtdDetail analysisOnWayInfo(Map map) {

        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        OrderOtdDetail orderOtdDetail = new OrderOtdDetail();
        if (map == null)
            return orderOtdDetail;

        try {
            // 明细 id
            if (!StringUtils.isEmpty(map.get("tid"))) {
                orderOtdDetail.settId(map.get("tid").toString());
            }
            // 在途时间
            if (!StringUtils.isEmpty(map.get("dtlocation"))) {
                orderOtdDetail.setTrackTime(simpleDateFormat.parse(map.get("dtlocation").toString()));
            }
            // 所在省
            if (!StringUtils.isEmpty(map.get("vcprovince"))) {
                orderOtdDetail.setProvince(map.get("vcprovince").toString());
            }
            // 所在市
            if (!StringUtils.isEmpty(map.get("vccity"))) {
                orderOtdDetail.setCity(map.get("vccity").toString());
            }
            // 所在区/县
            if (!StringUtils.isEmpty(map.get("vcarea"))) {
                orderOtdDetail.setArea(map.get("vcarea").toString());
            }
            // 详细地址
            if (!StringUtils.isEmpty(map.get("vclocation"))) {
                orderOtdDetail.setAddress(map.get("vclocation").toString());
            }
            // 经度
            if (!StringUtils.isEmpty(map.get("vclongitude"))) {
                orderOtdDetail.setLongitude(new BigDecimal(map.get("vclongitude").toString()));
            }
            // 纬度
            if (!StringUtils.isEmpty(map.get("vclatitude"))) {
                orderOtdDetail.setLatitude(new BigDecimal(map.get("vclatitude").toString()));
            }
            // 系统订单号
            if (!StringUtils.isEmpty(map.get("vcdn"))) {
                orderOtdDetail.setSysOrderNo(map.get("vcdn").toString());
            }
        } catch (Exception e) {
            LOGGER.error("OrderScheduled.analysisOnWayInfo ERROR: ", e);
        }

        return orderOtdDetail;
    }

    /**
     * 将ResponseEntity结果转换成map集合
     * @param result
     * @return
     */
    private List<Map> getMap(String result) {

        List<Map> dataMapList = new ArrayList<Map>();

        JSONObject json = JSONObject.parseObject(result);

        if (json==null || json.get("data")==null)
            return dataMapList;

        JSONArray jsonArray = JSONArray.parseArray(json.get("data").toString());

        if (jsonArray==null || jsonArray.size()==0)
            return dataMapList;

        // 遍历订单JSON串，一一转换成map
        for (Object obj : jsonArray) {
            Map map = (Map) obj;
            dataMapList.add(map);
        }

        return dataMapList;
    }
}
